
<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      <link rel="icon" href="../../../../static/images/favicon.png">
      <meta name="generator" content="mkdocs-1.3.0, mkdocs-material-8.2.8">
    
    
      
        <title>MySQL MGR + ShardingProxy + Keepalived + HAProxy + mysqld_exporter 高可用企业级生产部署 - WL4G DOCS</title>
      
    
    
      <link rel="stylesheet" href="../../../../assets/stylesheets/main.644de097.min.css">
      
        
        <link rel="stylesheet" href="../../../../assets/stylesheets/palette.e6a45f82.min.css">
        
      
    
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
      <link rel="stylesheet" href="../../../../static/css/util.css">
    
    <script>__md_scope=new URL("../../../..",location),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
  </head>
  
  
    
    
      
    
    
    
    
    <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="" data-md-color-accent="">
  
    
    
      <script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#mysql-mgr-shardingproxy-keepalived-haproxy-mysqld_exporter" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      <div data-md-component="outdated" hidden>
        <aside class="md-banner md-banner--warning">
          
        </aside>
      </div>
    
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href="../../../.." title="WL4G DOCS" class="md-header__button md-logo" aria-label="WL4G DOCS" data-md-component="logo">
      
  <img src="../../../../static/images/mylogo.jpeg" alt="logo">

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            WL4G DOCS
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              MySQL MGR + ShardingProxy + Keepalived + HAProxy + mysqld_exporter 高可用企业级生产部署
            
          </span>
        </div>
      </div>
    </div>
    
      <form class="md-header__option" data-md-component="palette">
        
          
          
          <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="" data-md-color-accent=""  aria-label="Switch to dark mode"  type="radio" name="__palette" id="__palette_1">
          
            <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6zm0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4zM7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>
            </label>
          
        
          
          
          <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="" data-md-color-accent=""  aria-label="Switch to light mode"  type="radio" name="__palette" id="__palette_2">
          
            <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3z"/></svg>
            </label>
          
        
      </form>
    
    
      <div class="md-header__option">
        <div class="md-select">
          
          <button class="md-header__button md-icon" aria-label="Select language">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m12.87 15.07-2.54-2.51.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04M18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12m-2.62 7 1.62-4.33L19.12 17h-3.24z"/></svg>
          </button>
          <div class="md-select__inner">
            <ul class="md-select__list">
              
                <li class="md-select__item">
                  <a href="/en/" hreflang="en" class="md-select__link">
                    English
                  </a>
                </li>
                
                <li class="md-select__item">
                  <a href="/zh/" hreflang="zh" class="md-select__link">
                    简体中文
                  </a>
                </li>
                
            </ul>
          </div>
        </div>
      </div>
    
    
      <label class="md-header__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
        </button>
      </nav>
      
        <div class="md-search__suggest" data-md-component="search-suggest"></div>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
            
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
  <div class="md-tabs__inner md-grid">
    <ul class="md-tabs__list">
      
        
  
  


  
  
  
    <li class="md-tabs__item">
      <a href="../../../.." class="md-tabs__link">
        Getting Started
      </a>
    </li>
  

      
    </ul>
  </div>
</nav>
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

  


  

<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href="../../../.." title="WL4G DOCS" class="md-nav__button md-logo" aria-label="WL4G DOCS" data-md-component="logo">
      
  <img src="../../../../static/images/mylogo.jpeg" alt="logo">

    </a>
    WL4G DOCS
  </label>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      

  
  
  
    
    <li class="md-nav__item md-nav__item--nested">
      
      
        <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_1" data-md-state="indeterminate" type="checkbox" id="__nav_1" checked>
      
      
      
      
        <label class="md-nav__link" for="__nav_1">
          Getting Started
          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <nav class="md-nav" aria-label="Getting Started" data-md-level="1">
        <label class="md-nav__title" for="__nav_1">
          <span class="md-nav__icon md-icon"></span>
          Getting Started
        </label>
        <ul class="md-nav__list" data-md-scrollfix>
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../../../.." class="md-nav__link">
        Introduction
      </a>
    </li>
  

            
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../../../../ABOUT_CN/" class="md-nav__link">
        About
      </a>
    </li>
  

            
          
        </ul>
      </nav>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
          
          <div class="md-content" data-md-component="content">
            <article class="md-content__inner md-typeset">
              
                


<h1 id="mysql-mgr-shardingproxy-keepalived-haproxy-mysqld_exporter">MySQL MGR + ShardingProxy + Keepalived + HAProxy + mysqld_exporter 高可用企业级生产部署<a class="headerlink" href="#mysql-mgr-shardingproxy-keepalived-haproxy-mysqld_exporter" title="Permanent link">&para;</a></h1>
<h2 id="1-mysql-group-replication">1. 首先部署 MySQL Group Replication 集群<a class="headerlink" href="#1-mysql-group-replication" title="Permanent link">&para;</a></h2>
<ul>
<li><a href="https://blogs.wl4g.com/archives/650">参见另一篇: MySQL MGR 生产高可用部署</a></li>
</ul>
<h2 id="2-haproxy">2. <code>HAProxy</code> 部署<a class="headerlink" href="#2-haproxy" title="Permanent link">&para;</a></h2>
<ul>
<li>
<p>方式 1：已编译好的离线包下载<br />
<a href="https://github.com/wl4g-collect/haproxy/releases">https://github.com/wl4g-collect/haproxy/releases</a>
<a href="https://gitee.com/wl4g-collect/haproxy/releases/v2.4.0">https://gitee.com/wl4g-collect/haproxy/releases/v2.4.0</a>
<a href="http://download.openpkg.org/components/cache/haproxy/">http://download.openpkg.org/components/cache/haproxy/</a></p>
</li>
<li>
<p>方式 2：<a href="#1.1&nbsp;从源码编译">从源码编译</a></p>
</li>
</ul>
<h3 id="21">2.1&nbsp;从源码编译<a class="headerlink" href="#21" title="Permanent link">&para;</a></h3>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1"></a><a href="#__codelineno-0-1"><span class="linenos" data-linenos=" 1 "></span></a>$ git clone https://github.com/haproxy/haproxy.git
<a id="__codelineno-0-2" name="__codelineno-0-2"></a><a href="#__codelineno-0-2"><span class="linenos" data-linenos=" 2 "></span></a>$ <span class="nb">cd</span> haproxy
<a id="__codelineno-0-3" name="__codelineno-0-3"></a><a href="#__codelineno-0-3"><span class="linenos" data-linenos=" 3 "></span></a>$ git checkout v2.4.0
<a id="__codelineno-0-4" name="__codelineno-0-4"></a><a href="#__codelineno-0-4"><span class="linenos" data-linenos=" 4 "></span></a>$ sudo make <span class="nv">TARGET</span><span class="o">=</span>linux-glibc <span class="nv">ARCH</span><span class="o">=</span>X86_64 <span class="nv">PREFIX</span><span class="o">=</span><span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>
<a id="__codelineno-0-5" name="__codelineno-0-5"></a><a href="#__codelineno-0-5"><span class="linenos" data-linenos=" 5 "></span></a><span class="c1"># 耐心等待编译完成..</span>
<a id="__codelineno-0-6" name="__codelineno-0-6"></a><a href="#__codelineno-0-6"><span class="linenos" data-linenos=" 6 "></span></a>$ ./haproxy -version
<a id="__codelineno-0-7" name="__codelineno-0-7"></a><a href="#__codelineno-0-7"><span class="linenos" data-linenos=" 7 "></span></a>$ sudo cp <span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>/haproxy /bin/
<a id="__codelineno-0-8" name="__codelineno-0-8"></a><a href="#__codelineno-0-8"><span class="linenos" data-linenos=" 8 "></span></a>
<a id="__codelineno-0-9" name="__codelineno-0-9"></a><a href="#__codelineno-0-9"><span class="linenos" data-linenos=" 9 "></span></a>HAProxy version <span class="m">2</span>.4.0 <span class="m">2021</span>/05/14 - https://haproxy.org/
<a id="__codelineno-0-10" name="__codelineno-0-10"></a><a href="#__codelineno-0-10"><span class="linenos" data-linenos="10 "></span></a>Status: long-term supported branch - will stop receiving fixes around Q2 <span class="m">2026</span>.
<a id="__codelineno-0-11" name="__codelineno-0-11"></a><a href="#__codelineno-0-11"><span class="linenos" data-linenos="11 "></span></a>Known bugs: http://www.haproxy.org/bugs/bugs-2.4.0.html
<a id="__codelineno-0-12" name="__codelineno-0-12"></a><a href="#__codelineno-0-12"><span class="linenos" data-linenos="12 "></span></a>Running on: Linux <span class="m">5</span>.4.0-77-generic <span class="c1">#86-Ubuntu SMP Thu Jun 17 02:35:03 UTC 2021 x86_64</span>
</code></pre></div>
<h3 id="22">2.2 配置<a class="headerlink" href="#22" title="Permanent link">&para;</a></h3>
<h4 id="221">2.2.1 环境配置<a class="headerlink" href="#221" title="Permanent link">&para;</a></h4>
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1"></a><a href="#__codelineno-1-1"><span class="linenos" data-linenos="1 "></span></a>sudo mkdir -p /etc/sysconfig/
<a id="__codelineno-1-2" name="__codelineno-1-2"></a><a href="#__codelineno-1-2"><span class="linenos" data-linenos="2 "></span></a>sudo tee /etc/sysconfig/haproxy <span class="s">&lt;&lt;-&#39;EOF&#39;</span>
<a id="__codelineno-1-3" name="__codelineno-1-3"></a><a href="#__codelineno-1-3"><span class="linenos" data-linenos="3 "></span></a><span class="s"># Add extra options to the haproxy daemon here. This can be useful for</span>
<a id="__codelineno-1-4" name="__codelineno-1-4"></a><a href="#__codelineno-1-4"><span class="linenos" data-linenos="4 "></span></a><span class="s"># specifying multiple configuration files with multiple -f options.</span>
<a id="__codelineno-1-5" name="__codelineno-1-5"></a><a href="#__codelineno-1-5"><span class="linenos" data-linenos="5 "></span></a><span class="s"># See haproxy(1) for a complete list of options.</span>
<a id="__codelineno-1-6" name="__codelineno-1-6"></a><a href="#__codelineno-1-6"><span class="linenos" data-linenos="6 "></span></a><span class="s">OPTIONS=&quot;&quot;</span>
<a id="__codelineno-1-7" name="__codelineno-1-7"></a><a href="#__codelineno-1-7"><span class="linenos" data-linenos="7 "></span></a><span class="s">EOF</span>
</code></pre></div>
<h4 id="222">2.2.2 规则配置<a class="headerlink" href="#222" title="Permanent link">&para;</a></h4>
<p><details style="cursor:pointer;;padding-left:2%">
<summary style="color:#007acc;">[展开] Configure haproxy.cfg</summary>
<code><pre>
sudo mkdir -p /etc/haproxy
sudo mkdir -p /var/lib/haproxy # Using for haproxy unix socks stats
sudo tee /etc/haproxy/haproxy.cfg <<-'EOF'
#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
#---------------------------------------------------------------------

global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    #
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    #
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     50000
    user        root
    group       root
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http # tcp|http|health
    log                     global
    option                  tcplog # tcplog|httplog
    option                  dontlognull
    option http-server-close
    #option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 50000

# Must setup mode=http to be effective, defaults{mode=http} is also possible.
# see: https://www.haproxy.com/blog/haproxy-exposes-a-prometheus-metrics-endpoint/
frontend stats
   bind *:8404
   #option http-use-htx
   #http-request use-service prometheus-exporter if { path /metrics }
   stats enable
   stats uri /stats
   stats refresh 10s

frontend mysql_cluster1
    bind *:3306
    mode        tcp
    default_backend     shardingproxy_cluster1

backend shardingproxy_cluster1
    balance     roundrobin
    mode        tcp
    server      shardingproxy1 10.0.0.162:3307 check
    server      shardingproxy2 10.0.0.163:3307 check
    server      shardingproxy3 10.0.0.163:3307 check
EOF
</pre></code>
</details></p>

<ul>
<li>检查规则配置合法(可选)</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1"></a><a href="#__codelineno-2-1"><span class="linenos" data-linenos="1 "></span></a>$ haproxy -c -f /etc/haproxy/haproxy.cfg
<a id="__codelineno-2-2" name="__codelineno-2-2"></a><a href="#__codelineno-2-2"><span class="linenos" data-linenos="2 "></span></a>Configuration file is valid
</code></pre></div>
<h4 id="223">2.2.3 服务配置<a class="headerlink" href="#223" title="Permanent link">&para;</a></h4>
<p><details style="cursor:pointer;;padding-left:2%">
<summary style="color:#007acc;">[展开] Installation haproxy.service</summary>
<code><pre>
sudo tee /etc/systemd/system/haproxy.service <<-'EOF'
[Unit]
Description=HAProxy Load Balancer
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=-/etc/sysconfig/haproxy
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock"
ExecStartPre=/bin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecStart=/bin/haproxy -DWs -f $CONFIG -p $PIDFILE $EXTRAOPTS
ExecReload=/bin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecReload=/bin/kill -USR2 $MAINPID
StandardOutput=journal
StandardError=journal
KillMode=mixed
Restart=always
User=root
Group=root
SuccessExitStatus=143
Type=forking

# The following lines leverage SystemD's sandboxing options to provide
# defense in depth protection at the expense of restricting some flexibility
# in your setup (e.g. placement of your configuration files) or possibly
# reduced performance. See systemd.service(5) and systemd.exec(5) for further
# information.

# NoNewPrivileges=true
# ProtectHome=true
# If you want to use 'ProtectSystem=strict' you should whitelist the PIDFILE,
# any state files and any other files written using 'ReadWritePaths' or
# 'RuntimeDirectory'.
# ProtectSystem=true
# ProtectKernelTunables=true
# ProtectKernelModules=true
# ProtectControlGroups=true
# If your SystemD version supports them, you can add: @reboot, @swap, @sync
# SystemCallFilter=~@cpu-emulation @keyring @module @obsolete @raw-io

[Install]
WantedBy=multi-user.target
EOF
</pre></code>
</details></p>

<h4 id="224">2.2.4 启动服务<a class="headerlink" href="#224" title="Permanent link">&para;</a></h4>
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1"></a><a href="#__codelineno-3-1"><span class="linenos" data-linenos="1 "></span></a>sudo systemctl daemon-reload
<a id="__codelineno-3-2" name="__codelineno-3-2"></a><a href="#__codelineno-3-2"><span class="linenos" data-linenos="2 "></span></a>sudo systemctl <span class="nb">enable</span> haproxy
<a id="__codelineno-3-3" name="__codelineno-3-3"></a><a href="#__codelineno-3-3"><span class="linenos" data-linenos="3 "></span></a>sudo systemctl restart haproxy
<a id="__codelineno-3-4" name="__codelineno-3-4"></a><a href="#__codelineno-3-4"><span class="linenos" data-linenos="4 "></span></a>sudo systemctl status haproxy
<a id="__codelineno-3-5" name="__codelineno-3-5"></a><a href="#__codelineno-3-5"><span class="linenos" data-linenos="5 "></span></a><span class="c1"># 查看日志</span>
<a id="__codelineno-3-6" name="__codelineno-3-6"></a><a href="#__codelineno-3-6"><span class="linenos" data-linenos="6 "></span></a>sudo tail -f /var/log/syslog
<a id="__codelineno-3-7" name="__codelineno-3-7"></a><a href="#__codelineno-3-7"><span class="linenos" data-linenos="7 "></span></a><span class="c1"># sudo tail -f /var/log/message</span>
</code></pre></div>
<hr />
<h2 id="3-keepalived">3. <code>Keepalived</code> 部署<a class="headerlink" href="#3-keepalived" title="Permanent link">&para;</a></h2>
<ul>
<li>
<p>官方用户指南: <a href="https://www.keepalived.org/pdf/UserGuide.pdf">keepalived.org/pdf/UserGuide.pdf</a></p>
</li>
<li>
<p>方式1：已编译好的离线包下载
<a href="https://github.com/wl4g-collect/keepalived/releases">https://github.com/wl4g-collect/keepalived/releases</a>
<a href="https://gitee.com/wl4g-collect/keepalived/releases/v2.2.2">https://gitee.com/wl4g-collect/keepalived/releases/v2.2.2</a></p>
</li>
<li>
<p>方式2：<a href="#2.1&nbsp;从源码编译">从源码编译</a></p>
</li>
</ul>
<h3 id="31">3.1&nbsp;从源码编译<a class="headerlink" href="#31" title="Permanent link">&para;</a></h3>
<p><details style="cursor:pointer;;padding-left:2%">
<summary style="color:#007acc;">[展开] Installation keepalived</summary>
<code><pre>
# 前置依赖
sudo yum -y install openssl-devel autoconf automake
# 克隆源码
git clone https://github.com/acassen/keepalived.git
cd keepalived
# 从 configure.ac 生成 configure
./autogen.sh
# 生成 Makefile
chmod +x ./configure; ./configure --prefix=$(pwd)
# 编译安装
make && make install
# 查看编译产物
$ ./keepalived/keepalived --version

Keepalived v2.2.2 (03/05,2021)

Copyright(C) 2001-2021 Alexandre Cassen, <acassen@gmail.com>

Built with kernel headers for Linux 3.10.0
Running on Linux 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019
Distro: CentOS Linux 7 (Core)

configure options: --prefix=/root/keepalived

Config options:  LVS VRRP VRRP_AUTH VRRP_VMAC OLD_CHKSUM_COMPAT INIT=systemd
System options:  VSYSLOG RTA_ENCAP RTA_EXPIRES RTA_PREF FRA_TUN_ID RTAX_CC_ALGO RTAX_QUICKACK IFA_FLAGS NET_LINUX_IF_H_COLLISION NET_LINUX_IF_ETHER_H_COLLISION LIBIPTC_LINUX_NET_IF_H_COLLISION IFLA_LINK_NETNSID GLOB_BRACE GLOB_ALTDIRFUNC INET6_ADDR_GEN_MODE SO_MARK
</pre></code>
</details></p>

<h3 id="32">3.2 配置<a class="headerlink" href="#32" title="Permanent link">&para;</a></h3>
<h4 id="321">3.2.1 环境配置<a class="headerlink" href="#321" title="Permanent link">&para;</a></h4>
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1"></a><a href="#__codelineno-4-1"><span class="linenos" data-linenos=" 1 "></span></a>sudo mkdir -p /etc/keepalived
<a id="__codelineno-4-2" name="__codelineno-4-2"></a><a href="#__codelineno-4-2"><span class="linenos" data-linenos=" 2 "></span></a>sudo cat<span class="s">&lt;&lt;EOF&gt;/etc/keepalived/keepalived</span>
<a id="__codelineno-4-3" name="__codelineno-4-3"></a><a href="#__codelineno-4-3"><span class="linenos" data-linenos=" 3 "></span></a><span class="s"># Options for keepalived. See &#39;keepalived --help&#39; output and keepalived(8) and</span>
<a id="__codelineno-4-4" name="__codelineno-4-4"></a><a href="#__codelineno-4-4"><span class="linenos" data-linenos=" 4 "></span></a><span class="s"># keepalived.conf(5) man pages for a list of all options. Here are the most</span>
<a id="__codelineno-4-5" name="__codelineno-4-5"></a><a href="#__codelineno-4-5"><span class="linenos" data-linenos=" 5 "></span></a><span class="s"># common ones :</span>
<a id="__codelineno-4-6" name="__codelineno-4-6"></a><a href="#__codelineno-4-6"><span class="linenos" data-linenos=" 6 "></span></a><span class="s">#</span>
<a id="__codelineno-4-7" name="__codelineno-4-7"></a><a href="#__codelineno-4-7"><span class="linenos" data-linenos=" 7 "></span></a><span class="s"># --vrrp               -P    Only run with VRRP subsystem.</span>
<a id="__codelineno-4-8" name="__codelineno-4-8"></a><a href="#__codelineno-4-8"><span class="linenos" data-linenos=" 8 "></span></a><span class="s"># --check              -C    Only run with Health-checker subsystem.</span>
<a id="__codelineno-4-9" name="__codelineno-4-9"></a><a href="#__codelineno-4-9"><span class="linenos" data-linenos=" 9 "></span></a><span class="s"># --dont-release-vrrp  -V    Dont remove VRRP VIPs &amp; VROUTEs on daemon stop.</span>
<a id="__codelineno-4-10" name="__codelineno-4-10"></a><a href="#__codelineno-4-10"><span class="linenos" data-linenos="10 "></span></a><span class="s"># --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop.</span>
<a id="__codelineno-4-11" name="__codelineno-4-11"></a><a href="#__codelineno-4-11"><span class="linenos" data-linenos="11 "></span></a><span class="s"># --dump-conf          -d    Dump the configuration data.</span>
<a id="__codelineno-4-12" name="__codelineno-4-12"></a><a href="#__codelineno-4-12"><span class="linenos" data-linenos="12 "></span></a><span class="s"># --log-detail         -D    Detailed log messages.</span>
<a id="__codelineno-4-13" name="__codelineno-4-13"></a><a href="#__codelineno-4-13"><span class="linenos" data-linenos="13 "></span></a><span class="s"># --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON)</span>
<a id="__codelineno-4-14" name="__codelineno-4-14"></a><a href="#__codelineno-4-14"><span class="linenos" data-linenos="14 "></span></a><span class="s">#</span>
<a id="__codelineno-4-15" name="__codelineno-4-15"></a><a href="#__codelineno-4-15"><span class="linenos" data-linenos="15 "></span></a>
<a id="__codelineno-4-16" name="__codelineno-4-16"></a><a href="#__codelineno-4-16"><span class="linenos" data-linenos="16 "></span></a><span class="s">KEEPALIVED_OPTIONS=&quot;-D&quot;</span>
<a id="__codelineno-4-17" name="__codelineno-4-17"></a><a href="#__codelineno-4-17"><span class="linenos" data-linenos="17 "></span></a><span class="s">EOF</span>
</code></pre></div>
<h4 id="323">3.2.3 规则配置<a class="headerlink" href="#323" title="Permanent link">&para;</a></h4>
<p><details style="cursor:pointer;;padding-left:2%">
<summary style="color:#007acc;">[展开] Configure keepalived.conf</summary>
<code><pre>
sudo mkdir -p /etc/keepalived
sudo cat<<EOF>/etc/keepalived/keepalived.conf
global_defs {
  notification_email {
    983708408@qq.com # 通知接受邮箱 (**可按实际配置**)
  }
  notification_email_from xxx@163.com # 通知发送邮箱 (**可按实际配置**)
  smtp_server smtp.163.com # 邮箱主机 (**可按实际配置**)
  smtp_connect_timeout 10
  router_id  iloqg8n3yb9mje1s
  script_user root
  enable_script_security
  vrrp_garp_interval 0
  vrrp_garp_master_delay 40
  vrrp_garp_master_refresh 60
  vrrp_skip_check_adv_addr
  vrrp_gna_interval 0
  #vrrp_strict
}

vrrp_script haproxy_checkpoint {
  script "/etc/keepalived/haproxy_checker.sh" # 用于检测 real-ip 上服务的自定义脚本 (**可按实际配置**)
  interval 2
  weight 2
}

vrrp_instance keepalived_1 {
  interface eth0 # 使用网卡 (**可按实际配置**)
  virtual_router_id 51 # 虚拟路由的标志,  一组lvs的虚拟路由标识必须相同, 这样才能切换
  priority 150 # 服务启动优先级, 值越大优先级越高, BACKUP 不能大于MASTER
  advert_int 3 # 服务器之间的存活检查时间
  # 通常如果master服务死掉后backup会变成master, 但是当master服务又好了的时候 master 此时会抢占VIP,
  # 这样就会发生两次切换对业务繁忙的网站来说是不好的。所以我们要在配置文件加入 nopreempt 非抢占,
  # 但是这个参数只能用于state 为backup, 故我们在用HA的时候最好 master 和 backup 的 state 都设置成 BACKUP
  # 让其通过 priority 来竞争。
  state BACKUP # MASTER|BACKUP, 可将所有节点都设置为BACKUP时, 第一个启动时会抢占为 MASTER
  nopreempt # 指定非抢占
  authentication {
    auth_type PASS # 认证类型
    auth_pass ufsoft # 认证密码, 一组lvs 服务器的认证密码必须一致
  }

  track_script {
    haproxy_checkpoint # 执行监控 haproxy 进程的脚本
  }

  # 极力推荐显示指定广播 peer, 生产踩过的坑: 当时未指定此配置,
  # 可能会导致VRRPv2包被发到 vrrp.mcast.net 去了, 最终导致闹裂 (可通过 tcpdump -i any vrrp 捕包排查).
  unicast_src_ip 10.111.0.112
  unicast_peer {
    10.111.0.111
    10.111.0.112
  }

  # 虚拟IP地址
  virtual_ipaddress {
    10.111.0.200 # 虚拟vip (**可按实际配置**)
  }
}
EOF
</pre></code>
</details></p>

<h4 id="324">3.2.4 自定义探测脚本<a class="headerlink" href="#324" title="Permanent link">&para;</a></h4>
<p><details style="cursor:pointer;;padding-left:2%">
<summary style="color:#007acc;">[展开] Configure haproxy_checker.sh</summary>
<code><pre>
sudo tee /etc/keepalived/haproxy_checker.sh <<-'EOF'
#!/bin/bash

BASE_DIR=$(cd `dirname $0`; pwd)
APP_NAME=$(echo `basename $0`)
LOG_DIR="/mnt/disk1/log/keepalived"; mkdir -p $LOG_DIR
LOG_FILE="${LOG_DIR}/$(echo $APP_NAME|sed 's/.sh//g').stdout"

if [ -z "$(ps -ef | grep '/bin/haproxy'| grep -v grep)" ]; then
  echo "$(date '+%Y-%m-%d %H:%M:%S') - HAProxy is dead." | tee -a "$LOG_FILE"
  systemctl stop keepalived
else
  echo "$(date '+%Y-%m-%d %H:%M:%S') - HAPorxy is running." | tee -a "$LOG_FILE"
fi
exit 0
EOF

sudo chmod +x /etc/keepalived/haproxy_checker.sh
</pre></code>
</details></p>

<h4 id="325">3.2.5 服务配置<a class="headerlink" href="#325" title="Permanent link">&para;</a></h4>
<p><details style="cursor:pointer;;padding-left:2%">
<summary style="color:#007acc;">[展开] Configure keepalived.service(systemd)</summary>
<code><pre>
sudo tee /etc/systemd/system/keepalived.service <<-'EOF'
[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/keepalived/keepalived
ExecStart=/sbin/keepalived $KEEPALIVED_OPTIONS -f /etc/keepalived/keepalived.conf
ExecReload=/bin/kill -HUP $MAINPID
#StandardOutput=/mnt/disk1/log/keepalived.out
StandardError=journal
TimeoutStartSec=5
TimeoutSec=600
Restart=alway

[Install]
WantedBy=multi-user.target
EOF
</pre></code>
</details></p>

<h4 id="325_1">3.2.5 启动服务<a class="headerlink" href="#325_1" title="Permanent link">&para;</a></h4>
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1"></a><a href="#__codelineno-5-1"><span class="linenos" data-linenos="1 "></span></a>sudo systemctl daemon-reload
<a id="__codelineno-5-2" name="__codelineno-5-2"></a><a href="#__codelineno-5-2"><span class="linenos" data-linenos="2 "></span></a>sudo systemctl <span class="nb">enable</span> keepalived
<a id="__codelineno-5-3" name="__codelineno-5-3"></a><a href="#__codelineno-5-3"><span class="linenos" data-linenos="3 "></span></a>sudo systemctl restart keepalived
<a id="__codelineno-5-4" name="__codelineno-5-4"></a><a href="#__codelineno-5-4"><span class="linenos" data-linenos="4 "></span></a>sudo systemctl status keepalived
<a id="__codelineno-5-5" name="__codelineno-5-5"></a><a href="#__codelineno-5-5"><span class="linenos" data-linenos="5 "></span></a><span class="c1"># 查看日志</span>
<a id="__codelineno-5-6" name="__codelineno-5-6"></a><a href="#__codelineno-5-6"><span class="linenos" data-linenos="6 "></span></a>sudo tail -f /var/log/syslog
<a id="__codelineno-5-7" name="__codelineno-5-7"></a><a href="#__codelineno-5-7"><span class="linenos" data-linenos="7 "></span></a><span class="c1"># sudo tail -f /var/log/message</span>
<a id="__codelineno-5-8" name="__codelineno-5-8"></a><a href="#__codelineno-5-8"><span class="linenos" data-linenos="8 "></span></a><span class="c1"># 查看 vip 漂移状态 (keepalived主节点上应有 192.168.1.200)</span>
<a id="__codelineno-5-9" name="__codelineno-5-9"></a><a href="#__codelineno-5-9"><span class="linenos" data-linenos="9 "></span></a>ip addr
</code></pre></div>
<hr />
<h2 id="4-sharding-proxy">4. <code>Sharding Proxy</code> 部署<a class="headerlink" href="#4-sharding-proxy" title="Permanent link">&para;</a></h2>
<p>TODO</p>
<hr />
<h2 id="5">5. 全链路验证<a class="headerlink" href="#5" title="Permanent link">&para;</a></h2>
<p>TODO</p>
<h2 id="6">6. 部署监控 (可选推荐)<a class="headerlink" href="#6" title="Permanent link">&para;</a></h2>
<h3 id="61-haproxy_exporter">6.1 部署 <a href="https://github.com/wl4g-collect/haproxy_exporter">haproxy_exporter</a><a class="headerlink" href="#61-haproxy_exporter" title="Permanent link">&para;</a></h3>
<ul>
<li>
<p>注:  haproxy_exporter 最终调用的是 haproxy 进程的 /stats 接口获取的指标，<a href="https://www.haproxy.com/blog/haproxy-exposes-a-prometheus-metrics-endpoint/">官方 HAProxy 2.0 开始内置了 Prometheus 的原生支持</a></p>
</li>
<li>
<p>更多监控组件部署请参考: <a href="https://blogs.wl4g.com/archives/1885">Prometheus + Grafana + node_exporter + Alertmanager 快速主机部署</a></p>
</li>
<li>
<p>编译安装</p>
</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1"></a><a href="#__codelineno-6-1"><span class="linenos" data-linenos="1 "></span></a><span class="nb">cd</span> /tmp
<a id="__codelineno-6-2" name="__codelineno-6-2"></a><a href="#__codelineno-6-2"><span class="linenos" data-linenos="2 "></span></a>git clone https://github.com/wl4g-collect/haproxy_exporter.git
<a id="__codelineno-6-3" name="__codelineno-6-3"></a><a href="#__codelineno-6-3"><span class="linenos" data-linenos="3 "></span></a><span class="nb">cd</span> haproxy_exporter
<a id="__codelineno-6-4" name="__codelineno-6-4"></a><a href="#__codelineno-6-4"><span class="linenos" data-linenos="4 "></span></a>git checkout v0.12.0
<a id="__codelineno-6-5" name="__codelineno-6-5"></a><a href="#__codelineno-6-5"><span class="linenos" data-linenos="5 "></span></a>make build
<a id="__codelineno-6-6" name="__codelineno-6-6"></a><a href="#__codelineno-6-6"><span class="linenos" data-linenos="6 "></span></a>sudo chmod +x haproxy_exporter
<a id="__codelineno-6-7" name="__codelineno-6-7"></a><a href="#__codelineno-6-7"><span class="linenos" data-linenos="7 "></span></a>cp haproxy_exporter /usr/sbin/
</code></pre></div>
<ul>
<li>运行配置</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1"></a><a href="#__codelineno-7-1"><span class="linenos" data-linenos="1 "></span></a>sudo cat <span class="s">&lt;&lt;-&#39;EOF&#39; &gt;/etc/sysconfig/haproxy_exporter</span>
<a id="__codelineno-7-2" name="__codelineno-7-2"></a><a href="#__codelineno-7-2"><span class="linenos" data-linenos="2 "></span></a><span class="s">OPTIONS=&#39;--no-haproxy.ssl-verify --haproxy.scrape-uri=&quot;http://localhost:8404/stats?stats;csv&quot;&#39;</span>
<a id="__codelineno-7-3" name="__codelineno-7-3"></a><a href="#__codelineno-7-3"><span class="linenos" data-linenos="3 "></span></a><span class="s">EOF</span>
</code></pre></div>
<ul>
<li>服务配置</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1"></a><a href="#__codelineno-8-1"><span class="linenos" data-linenos="1 "></span></a>sudo curl -o /etc/systemd/system/haproxy_exporter.service <span class="s1">&#39;https://raw.githubusercontent.com/wl4g/prometheus-integration/master/prometheus/haproxy/systemd/haproxy_exporter.service&#39;</span>
<a id="__codelineno-8-2" name="__codelineno-8-2"></a><a href="#__codelineno-8-2"><span class="linenos" data-linenos="2 "></span></a>
<a id="__codelineno-8-3" name="__codelineno-8-3"></a><a href="#__codelineno-8-3"><span class="linenos" data-linenos="3 "></span></a>sudo systemctl daemon-reload
<a id="__codelineno-8-4" name="__codelineno-8-4"></a><a href="#__codelineno-8-4"><span class="linenos" data-linenos="4 "></span></a>sudo systemctl <span class="nb">enable</span> haproxy_exporter
<a id="__codelineno-8-5" name="__codelineno-8-5"></a><a href="#__codelineno-8-5"><span class="linenos" data-linenos="5 "></span></a>sudo systemctl restart haproxy_exporter
<a id="__codelineno-8-6" name="__codelineno-8-6"></a><a href="#__codelineno-8-6"><span class="linenos" data-linenos="6 "></span></a>sudo systemctl status haproxy_exporter
<a id="__codelineno-8-7" name="__codelineno-8-7"></a><a href="#__codelineno-8-7"><span class="linenos" data-linenos="7 "></span></a>sudo journalctl -afu haproxy_exporter
</code></pre></div>
<ul>
<li>测试指标接口</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1"></a><a href="#__codelineno-9-1"><span class="linenos" data-linenos="1 "></span></a><span class="c1"># 先看看 haproxy /stats 接口正常与否</span>
<a id="__codelineno-9-2" name="__codelineno-9-2"></a><a href="#__codelineno-9-2"><span class="linenos" data-linenos="2 "></span></a>curl <span class="s2">&quot;http://localhost:8404/stats?;csv&quot;</span>
<a id="__codelineno-9-3" name="__codelineno-9-3"></a><a href="#__codelineno-9-3"><span class="linenos" data-linenos="3 "></span></a>
<a id="__codelineno-9-4" name="__codelineno-9-4"></a><a href="#__codelineno-9-4"><span class="linenos" data-linenos="4 "></span></a><span class="c1"># 再看看 haproxy_exporter 接口正常与否</span>
<a id="__codelineno-9-5" name="__codelineno-9-5"></a><a href="#__codelineno-9-5"><span class="linenos" data-linenos="5 "></span></a>curl <span class="s2">&quot;http://localhost:9101/metrics&quot;</span>
</code></pre></div>
<ul>
<li>Grafana 导入 haproxy 仪表盘</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1"></a><a href="#__codelineno-10-1"><span class="linenos" data-linenos="1 "></span></a>curl <span class="s1">&#39;https://raw.githubusercontent.com/wl4g/prometheus-integration/master/prometheus/haproxy/dashboard-haproxy-2428-rev7.json&#39;</span>
</code></pre></div>
<ul>
<li>Promethus 配置</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1"></a><a href="#__codelineno-11-1"><span class="linenos" data-linenos=" 1 "></span></a># 其他配置省略 ...
<a id="__codelineno-11-2" name="__codelineno-11-2"></a><a href="#__codelineno-11-2"><span class="linenos" data-linenos=" 2 "></span></a># ...
<a id="__codelineno-11-3" name="__codelineno-11-3"></a><a href="#__codelineno-11-3"><span class="linenos" data-linenos=" 3 "></span></a>scrape_configs:
<a id="__codelineno-11-4" name="__codelineno-11-4"></a><a href="#__codelineno-11-4"><span class="linenos" data-linenos=" 4 "></span></a>  - job_name: haproxy
<a id="__codelineno-11-5" name="__codelineno-11-5"></a><a href="#__codelineno-11-5"><span class="linenos" data-linenos=" 5 "></span></a>    static_configs:
<a id="__codelineno-11-6" name="__codelineno-11-6"></a><a href="#__codelineno-11-6"><span class="linenos" data-linenos=" 6 "></span></a>    - targets: [&#39;10.111.0.111:9101&#39;]
<a id="__codelineno-11-7" name="__codelineno-11-7"></a><a href="#__codelineno-11-7"><span class="linenos" data-linenos=" 7 "></span></a>      labels:
<a id="__codelineno-11-8" name="__codelineno-11-8"></a><a href="#__codelineno-11-8"><span class="linenos" data-linenos=" 8 "></span></a>        instance: collect-node1:9101
<a id="__codelineno-11-9" name="__codelineno-11-9"></a><a href="#__codelineno-11-9"><span class="linenos" data-linenos=" 9 "></span></a>    - targets: [&#39;10.111.0.112:9101&#39;]
<a id="__codelineno-11-10" name="__codelineno-11-10"></a><a href="#__codelineno-11-10"><span class="linenos" data-linenos="10 "></span></a>      labels:
<a id="__codelineno-11-11" name="__codelineno-11-11"></a><a href="#__codelineno-11-11"><span class="linenos" data-linenos="11 "></span></a>        instance: collect-node2:9101
</code></pre></div>
<h3 id="62-mysqld_exporter">6.2 部署 <a href="https://github.com/wl4g-collect/mysqld_exporter">mysqld_exporter</a><a class="headerlink" href="#62-mysqld_exporter" title="Permanent link">&para;</a></h3>
<ul>
<li>下载安装</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1"></a><a href="#__codelineno-12-1"><span class="linenos" data-linenos=" 1 "></span></a><span class="c1"># Downloading.</span>
<a id="__codelineno-12-2" name="__codelineno-12-2"></a><a href="#__codelineno-12-2"><span class="linenos" data-linenos=" 2 "></span></a>sudo <span class="nb">cd</span> /tmp
<a id="__codelineno-12-3" name="__codelineno-12-3"></a><a href="#__codelineno-12-3"><span class="linenos" data-linenos=" 3 "></span></a>sudo curl -OL https://github.91chifun.workers.dev/https://github.com//prometheus/mysqld_exporter/releases/download/v0.13.0/mysqld_exporter-0.13.0.linux-amd64.tar.gz
<a id="__codelineno-12-4" name="__codelineno-12-4"></a><a href="#__codelineno-12-4"><span class="linenos" data-linenos=" 4 "></span></a>sudo tar -xf mysqld_exporter*
<a id="__codelineno-12-5" name="__codelineno-12-5"></a><a href="#__codelineno-12-5"><span class="linenos" data-linenos=" 5 "></span></a>sudo cp mysqld_exporter*/mysqld_exporter /usr/bin/
<a id="__codelineno-12-6" name="__codelineno-12-6"></a><a href="#__codelineno-12-6"><span class="linenos" data-linenos=" 6 "></span></a>
<a id="__codelineno-12-7" name="__codelineno-12-7"></a><a href="#__codelineno-12-7"><span class="linenos" data-linenos=" 7 "></span></a><span class="c1"># Environment configuration.</span>
<a id="__codelineno-12-8" name="__codelineno-12-8"></a><a href="#__codelineno-12-8"><span class="linenos" data-linenos=" 8 "></span></a>sudo mkdir -p /etc/sysconfig
<a id="__codelineno-12-9" name="__codelineno-12-9"></a><a href="#__codelineno-12-9"><span class="linenos" data-linenos=" 9 "></span></a>sudo curl -o /etc/sysconfig/mysqld_exporter.conf <span class="s1">&#39;https://raw.githubusercontent.com/wl4g/prometheus-integration/master/prometheus/mysql/sysconfig/mysqld_exporter.conf&#39;</span>
<a id="__codelineno-12-10" name="__codelineno-12-10"></a><a href="#__codelineno-12-10"><span class="linenos" data-linenos="10 "></span></a>
<a id="__codelineno-12-11" name="__codelineno-12-11"></a><a href="#__codelineno-12-11"><span class="linenos" data-linenos="11 "></span></a><span class="c1"># Connect mysqld configuration.</span>
<a id="__codelineno-12-12" name="__codelineno-12-12"></a><a href="#__codelineno-12-12"><span class="linenos" data-linenos="12 "></span></a>sudo curl -o /etc/sysconfig/mysqld_exporter.cnf <span class="s1">&#39;https://raw.githubusercontent.com/wl4g/prometheus-integration/master/prometheus/mysql/sysconfig/mysqld_exporter.cnf&#39;</span>
</code></pre></div>
<ul>
<li>配置服务</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1"></a><a href="#__codelineno-13-1"><span class="linenos" data-linenos=" 1 "></span></a>sudo curl -o /etc/systemd/system/mysqld_exporter.service <span class="s1">&#39;https://raw.githubusercontent.com/wl4g/prometheus-integration/master/prometheus/mysql/systemd/mysqld_exporter.service&#39;</span>
<a id="__codelineno-13-2" name="__codelineno-13-2"></a><a href="#__codelineno-13-2"><span class="linenos" data-linenos=" 2 "></span></a>
<a id="__codelineno-13-3" name="__codelineno-13-3"></a><a href="#__codelineno-13-3"><span class="linenos" data-linenos=" 3 "></span></a>sudo systemctl daemon-reload
<a id="__codelineno-13-4" name="__codelineno-13-4"></a><a href="#__codelineno-13-4"><span class="linenos" data-linenos=" 4 "></span></a>sudo systemctl <span class="nb">enable</span> mysqld_exporter
<a id="__codelineno-13-5" name="__codelineno-13-5"></a><a href="#__codelineno-13-5"><span class="linenos" data-linenos=" 5 "></span></a>sudo systemctl restart mysqld_exporter
<a id="__codelineno-13-6" name="__codelineno-13-6"></a><a href="#__codelineno-13-6"><span class="linenos" data-linenos=" 6 "></span></a>sudo systemctl status mysqld_exporter
<a id="__codelineno-13-7" name="__codelineno-13-7"></a><a href="#__codelineno-13-7"><span class="linenos" data-linenos=" 7 "></span></a>sudo journalctl -u mysqld_exporter -f
<a id="__codelineno-13-8" name="__codelineno-13-8"></a><a href="#__codelineno-13-8"><span class="linenos" data-linenos=" 8 "></span></a>
<a id="__codelineno-13-9" name="__codelineno-13-9"></a><a href="#__codelineno-13-9"><span class="linenos" data-linenos=" 9 "></span></a><span class="c1"># 测试访问</span>
<a id="__codelineno-13-10" name="__codelineno-13-10"></a><a href="#__codelineno-13-10"><span class="linenos" data-linenos="10 "></span></a>curl http://localhost:9104/metrics
</code></pre></div>
<ul>
<li>配置 mysql 账号</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1"></a><a href="#__codelineno-14-1"><span class="linenos" data-linenos="1 "></span></a><span class="k">CREATE</span><span class="w"> </span><span class="k">USER</span><span class="w"> </span><span class="o">`</span><span class="n">mysqld_exporter</span><span class="o">`@`</span><span class="mi">127</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">1</span><span class="o">`</span><span class="w"> </span><span class="n">IDENTIFIED</span><span class="w"> </span><span class="k">WITH</span><span class="w"> </span><span class="n">mysql_native_password</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="s1">&#39;mysqld_exporter&#39;</span><span class="p">;</span><span class="w"></span>
<a id="__codelineno-14-2" name="__codelineno-14-2"></a><a href="#__codelineno-14-2"><span class="linenos" data-linenos="2 "></span></a><span class="k">GRANT</span><span class="w"> </span><span class="n">Event</span><span class="p">,</span><span class="w"> </span><span class="n">Process</span><span class="p">,</span><span class="w"> </span><span class="n">Replication</span><span class="w"> </span><span class="n">Client</span><span class="p">,</span><span class="w"> </span><span class="k">Select</span><span class="p">,</span><span class="w"> </span><span class="k">Show</span><span class="w"> </span><span class="n">Databases</span><span class="p">,</span><span class="w"> </span><span class="k">Show</span><span class="w"> </span><span class="k">View</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="o">*</span><span class="p">.</span><span class="o">*</span><span class="w"> </span><span class="k">TO</span><span class="w"> </span><span class="o">`</span><span class="n">mysqld_exporter</span><span class="o">`@`</span><span class="mi">127</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">1</span><span class="o">`</span><span class="p">;</span><span class="w"></span>
<a id="__codelineno-14-3" name="__codelineno-14-3"></a><a href="#__codelineno-14-3"><span class="linenos" data-linenos="3 "></span></a><span class="n">FLUSH</span><span class="w"> </span><span class="k">PRIVILEGES</span><span class="p">;</span><span class="w"></span>
</code></pre></div>
<ul>
<li>Grafana 导入 mysqld_exporter 仪表盘</li>
</ul>
<p>mysqld_exporter 默认有提供 grafana <a href="https://gitee.com/wl4g-collect/mysqld_exporter/raw/master/mysqld-mixin/dashboards/mysql-overview.json">mysql-overview.json</a>、alert <a href="https://gitee.com/wl4g-collect/mysqld_exporter/raw/master/mysqld-mixin/alerts/galera.yaml">galera.yaml</a>、<a href="https://gitee.com/wl4g-collect/mysqld_exporter/raw/master/mysqld-mixin/alerts/general.yaml">general.yaml</a>、<a href="https://gitee.com/wl4g-collect/mysqld_exporter/raw/master/mysqld-mixin/rules/rules.yaml">rules.yaml</a>，参见：https://github.com/wl4g-collect/mysqld_exporter。</p>
<ul>
<li>Grafana dashboard 配置（例如以下手动下载 dashboard 然后导入）</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1"></a><a href="#__codelineno-15-1"><span class="linenos" data-linenos="1 "></span></a>curl -OL <span class="s1">&#39;https://raw.githubusercontent.com/wl4g-collect/mysqld_exporter/master/mysqld-mixin/dashboards/mysql-overview.json&#39;</span>
<a id="__codelineno-15-2" name="__codelineno-15-2"></a><a href="#__codelineno-15-2"><span class="linenos" data-linenos="2 "></span></a><span class="c1"># 或</span>
<a id="__codelineno-15-3" name="__codelineno-15-3"></a><a href="#__codelineno-15-3"><span class="linenos" data-linenos="3 "></span></a>curl -OL <span class="s1">&#39;https://gitee.com/wl4g-collect/mysqld_exporter/raw/master/mysqld-mixin/dashboards/mysql-overview.json&#39;</span>
</code></pre></div>
<ul>
<li>Promethus scrape 配置</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1"></a><a href="#__codelineno-16-1"><span class="linenos" data-linenos=" 1 "></span></a># 其他配置省略 ...
<a id="__codelineno-16-2" name="__codelineno-16-2"></a><a href="#__codelineno-16-2"><span class="linenos" data-linenos=" 2 "></span></a># ...
<a id="__codelineno-16-3" name="__codelineno-16-3"></a><a href="#__codelineno-16-3"><span class="linenos" data-linenos=" 3 "></span></a>scrape_configs:
<a id="__codelineno-16-4" name="__codelineno-16-4"></a><a href="#__codelineno-16-4"><span class="linenos" data-linenos=" 4 "></span></a>  - job_name: mysqld_exporter
<a id="__codelineno-16-5" name="__codelineno-16-5"></a><a href="#__codelineno-16-5"><span class="linenos" data-linenos=" 5 "></span></a>    static_configs:
<a id="__codelineno-16-6" name="__codelineno-16-6"></a><a href="#__codelineno-16-6"><span class="linenos" data-linenos=" 6 "></span></a>    - targets: [&#39;mysql-node1:9104&#39;]
<a id="__codelineno-16-7" name="__codelineno-16-7"></a><a href="#__codelineno-16-7"><span class="linenos" data-linenos=" 7 "></span></a>      labels:
<a id="__codelineno-16-8" name="__codelineno-16-8"></a><a href="#__codelineno-16-8"><span class="linenos" data-linenos=" 8 "></span></a>        instance: mysql-node1:9104
<a id="__codelineno-16-9" name="__codelineno-16-9"></a><a href="#__codelineno-16-9"><span class="linenos" data-linenos=" 9 "></span></a>    - targets: [&#39;mysql-node2:9104&#39;]
<a id="__codelineno-16-10" name="__codelineno-16-10"></a><a href="#__codelineno-16-10"><span class="linenos" data-linenos="10 "></span></a>      labels:
<a id="__codelineno-16-11" name="__codelineno-16-11"></a><a href="#__codelineno-16-11"><span class="linenos" data-linenos="11 "></span></a>        instance: mysql-node2:9104
<a id="__codelineno-16-12" name="__codelineno-16-12"></a><a href="#__codelineno-16-12"><span class="linenos" data-linenos="12 "></span></a>    - targets: [&#39;mysql-node3:9104&#39;]
<a id="__codelineno-16-13" name="__codelineno-16-13"></a><a href="#__codelineno-16-13"><span class="linenos" data-linenos="13 "></span></a>      labels:
<a id="__codelineno-16-14" name="__codelineno-16-14"></a><a href="#__codelineno-16-14"><span class="linenos" data-linenos="14 "></span></a>        instance: mysql-node3:9104
</code></pre></div>
<h2 id="7-faq">7. FAQ<a class="headerlink" href="#7-faq" title="Permanent link">&para;</a></h2>
<ul>
<li>7.1 当  <code>keepalived</code> master 宕机，vip成功转移到从机，但访问 vip 依然无法连接？</li>
<li>由于 <code>arp(ipv4)</code>/ <code>ndp(ipv6)</code> 路由表缓存未更新，清理缓存执行: <code>arping -I eth0 -c 3 -s 192.168.1.200 192.168.1.1</code></li>
</ul>
<h2 id="8-troubleshooting">8. Troubleshooting<a class="headerlink" href="#8-troubleshooting" title="Permanent link">&para;</a></h2>
<ul>
<li>
<p><a href="https://blog.csdn.net/weixin_34217711/article/details/85901053">参考 1:【重要】Keepalived 主备切换后的 arp 缓存问题</a></p>
</li>
<li>
<p><a href="https://www.wumingx.com/linux/keepalived.html">参考 2:【重要】keepalived 参数详解及脑裂分析</a></p>
</li>
<li><a href="https://github.com/acassen/keepalived/issues/1810">VRRP State for a particular VIP instance and its reflecting VRRP_MASTER</a></li>
<li>一般脑裂问题的排查思路有：</li>
<li><code>virtual_router_id</code>必须一样；</li>
<li>防火墙将 vrrp 广播包给过滤掉了（可使用<code>iptables -nL</code>检查规则，使用<code>tcpdump -i any vrrp</code>抓包分析）；</li>
<li>主机负载异常导致机器无法正常发送或收到vrrp包之后无足够CPU时间片处理，可尝试增加<code>advert_int</code>时间；</li>
<li>
<p>网卡异常等；</p>
</li>
<li>
<p><a href="https://help.aliyun.com/document_detail/110065.html?spm=a2c4g.11186623.6.630.732f6874EUJvgA">参考 3: 【重要】云主机默认可能不支持VIP，如: Aliyun HaVip documents</a></p>
</li>
<li>
<p><a href="https://blog.csdn.net/zzhongcy/article/details/88667220">参考 4: VIP / ARP / Keepalived实现VIP转移、LVS高可用详解</a></p>
</li>
<li>
<p><a href="https://mp.weixin.qq.com/s?__biz=MzI0ODk2NDIyMQ==&amp;mid=2247487804&amp;idx=1&amp;sn=f001a24a308053b3723dfb12d36045ee&amp;chksm=e999e42edeee6d383fbb411792e22e4028bb8c2441255786f50cf848443af7b1bd5e382078dc&amp;token=692920236&amp;lang=zh_CN#rd">参考 5: Arp 协议详解（如华为防火墙 Quidway Eudemon1000E 在默认配置下ARP路由表自动刷新频率为20分钟！）</a></p>
</li>
<li>
<p><a href="https://studygolang.com/articles/13645?fr=sidebar">参考 6: Go 操作链路层套接字的实践</a></p>
</li>
<li>
<p><a href="https://www.cnblogs.com/cxuanBlog/p/14600398.html">参考 7: 计算机网络链路层协议图解</a></p>
</li>
<li>
<p><a href="https://blogs.wl4g.com/archives/1885">参考 8: Prometheus + Grafana + node_exporter + Alertmanager 快速主机部署</a></p>
</li>
</ul>

              
            </article>
          </div>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
  
    Made with
    <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    <script id="__config" type="application/json">{"base": "../../../..", "features": ["search.suggest", "search.highlight", "navigation.tabs", "navigation.expand", "toc.follow", "toc.integrate"], "search": "../../../../assets/javascripts/workers/search.5e67fbfe.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version.title": "Select version"}, "version": {"default": "latest", "provider": "mike"}}</script>
    
    
      <script src="../../../../assets/javascripts/bundle.c44cc438.min.js"></script>
      
        <script src="../../../../static/js/util.js"></script>
      
    
  </body>
</html>